package org.libermundi.theorcs.core.services.impl;

import java.io.Serializable;

import org.libermundi.theorcs.core.dao.hibernate.GenericHibernateDaoFactory;
import org.libermundi.theorcs.core.dao.hibernate.HibernateDao;
import org.libermundi.theorcs.core.model.base.Identifiable;
import org.libermundi.theorcs.core.services.GenericManager;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

@Service("GenericManager")
@Transactional(rollbackFor = Exception.class, propagation=Propagation.REQUIRED)
public class GenericHibernateManagerImpl implements GenericManager {
	private static final Logger logger = LoggerFactory.getLogger(GenericHibernateManagerImpl.class);
	
	private final GenericHibernateDaoFactory _daoFactory;
	
	@Autowired
	public GenericHibernateManagerImpl(GenericHibernateDaoFactory daoFactory) {
		if(logger.isDebugEnabled()){
			logger.debug("Instanciate GenericHibernateManagerImpl");
		}
		_daoFactory=daoFactory;
	}

	/*
	 * (non-Javadoc)
	 * @see org.libermundi.theorcs.core.services.GenericManager#find(java.lang.Class, java.io.Serializable)
	 */
	@Override
	 public <T extends Identifiable<I>, I extends Serializable> T find(Class<T> clazz, I primaryKey) {
		return getDao(clazz).find(clazz, primaryKey);
	}
	
	/* (non-Javadoc)
	 * @see org.libermundi.theorcs.core.services.GenericManager#getLast(java.lang.Class)
	 */
	@Override
	public <T extends Identifiable<I>, I extends Serializable> T getLast(Class<T> clazz) {
		return getDao(clazz).loadLast();
	}


	/* (non-Javadoc)
	 * @see org.libermundi.theorcs.core.services.GenericManager#refresh(org.libermundi.theorcs.core.model.base.Identifiable)
	 */
	@SuppressWarnings("unchecked")
	@Override
	public <T extends Identifiable<I>, I extends Serializable> T refresh(final T obj) {
		T resfreshed = obj;
		if(obj != null){
			resfreshed = getDao((Class<T>)obj.getClass()).refresh(obj);
		}
		return resfreshed;
	}
	
	private <T extends Identifiable<I>, I extends Serializable> HibernateDao<T,I> getDao(Class<T> clazz){
		return _daoFactory.create(clazz);
	}

}
